import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from "@nestjs/common";
import { Reflector } from "@nestjs/core";
import { IS_PUBLIC_KEY } from "./public.decorator";
import { JwtService } from "@nestjs/jwt";
import { JWT_SECRET_KEY } from "./auth.jwt.secrect";

@Injectable()
export class AuthGuard implements CanActivate {
    constructor(
        private jwtService: JwtService,
        private reflector: Reflector
    ) {}
    // 实现一个canActive方法
    async canActivate(context: ExecutionContext): Promise<boolean> {
        const isPublic:boolean = this.reflector.getAllAndOverride(IS_PUBLIC_KEY, [
            context.getHandler(),
            context.getClass(),
        ])
        if(isPublic) {
            return true
        } 
        const request = context.switchToHttp().getRequest();
        const token = extratctTokenFromHeader(request)
        if(!token) {
            throw new UnauthorizedException({
                statusCode: 401,
                message: "Internal server error"
            })
        }
        // 需要使用jwt的方法token验证
        try {
            const payload = await this.jwtService.verifyAsync(token,{
                secret:JWT_SECRET_KEY
            })
            request['user'] = payload
        } catch (error) {
            console.log('error',error);
            throw new UnauthorizedException({
                statusCode: 401,
                message: "Internal server error"
            })
        }
        return true
    }
}

function extratctTokenFromHeader(request:any) {
    const [type,token] = request.headers.authorization?.split(' ') ?? []
    return type === 'Bearer' ? token : ''
}